package own.stu.jobgib.playown.util.ftp;

import org.springframework.beans.BeanUtils;
import sun.net.ftp.FtpClient;
import sun.net.ftp.FtpProtocolException;

import java.io.*;

/**
 * ftp 上传 指令
 */
public class FtpUploadCommand extends AbstractFtpCommand<FtpUploadParameter, Void>{

    @Override
    protected Void operate(FtpUploadParameter parameter) {

        File localFile = parameter.getLocalFile();
        FtpClient ftpClient = parameter.getFtpClient();
        boolean isOver = parameter.isOver();
        try {
            if (localFile.isDirectory()) {
                try {
                    ftpClient.changeDirectory(localFile.getName());
                } catch (Exception ex) {
                    ftpClient.makeDirectory(localFile.getName());
                    ftpClient.changeDirectory(localFile.getName());
                }
                String[] files = localFile.list();
                if(files == null){
                    return null;
                }
                File tempFile;
                for (String file : files) {
                    tempFile = new File(localFile.getPath() + "\\" + file);
                    if (tempFile.isDirectory()) {

                        FtpUploadParameter tmpParameter = new FtpUploadParameter();
                        BeanUtils.copyProperties(parameter, tmpParameter);
                        tmpParameter.setLocalFile(tempFile);
                        operate(parameter);

                        ftpClient.changeToParentDirectory();
                    } else {
                        tempFile = new File(localFile.getPath() + "\\" + file);
                        streamWrite(ftpClient, tempFile, isOver);
                    }
                }

            } else {
                streamWrite(ftpClient, localFile, isOver);
            }
        } catch (Exception e) {
            log.error("upload error: ", e);
            throw new RuntimeException(e.getMessage());
        }
        return null;
    }

    /**
     * 文件写入到ftp服务器
     *
     * @param localFile 本地文件
     * @param isOver    是否覆盖存在文件
     * @throws RuntimeException
     */
    @SuppressWarnings("restriction")
    private static void streamWrite(FtpClient ftpClient, File localFile, boolean isOver) throws RuntimeException, IOException, FtpProtocolException {
        if (!"".equals(ftpClient.getStatus(localFile.getName())) && !isOver) {
            //是否覆盖文件
            return;
        }

        try (OutputStream os = ftpClient.putFileStream(localFile.getName());
             InputStream is = new FileInputStream(localFile)) {
            // 创建一个缓冲区
            byte[] bytes = new byte[BUFF_SIZE];
            int c;
            while ((c = is.read(bytes)) > 0) {
                os.write(bytes, 0, c);
            }
        }
   }

    @Override
    protected void checkParameter(FtpUploadParameter parameter) {
        if (!parameter.getLocalFile().exists()) {
            throw new RuntimeException("local file is exists!");
        }
    }

    @Override
    public void setParameter(FtpUploadParameter parameter) {
        this.parameter = parameter;
    }
}
